package flc.ast.utils;

import android.content.Context;
import android.util.Log;

import java.io.*;
import java.net.*;
import java.util.*;


/**
 * @Author: LongZhiBin
 * @Date: 2025/6/23
 * @Description:
 */
public class AndroidFileServer {
    private int port;
    private ServerSocket serverSocket;
    private Context context;
    private File storageDir;
    private boolean isRunning = false;

    public AndroidFileServer(Context context, int port) {
        this.context = context;
        this.port = port;
        this.storageDir = new File(context.getExternalFilesDir(null), "server_files");
        if (!storageDir.exists()) storageDir.mkdirs();
    }

    public void start() throws IOException {
        if (isRunning) return;
        serverSocket = new ServerSocket(port);
        isRunning = true;

        new Thread(() -> {
            while (isRunning) {
                try {
                    Socket client = serverSocket.accept();
                    handleClient(client);
                } catch (IOException e) {
                    if (isRunning) e.printStackTrace();
                }
            }
        }).start();
    }

//    private void handleClient(Socket client) throws IOException {
//        BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
//        OutputStream out = client.getOutputStream();
//
//        String request = in.readLine();
//        if (request == null) return;
//
//        if (request.startsWith("GET")) {
//            handleGetRequest(request, new PrintWriter(out), out);
//        } else if (request.startsWith("POST")) {
//            handlePostRequest(client.getInputStream(), out);
//        }
//        client.close();
//    }

    private void handleClient(Socket client) throws IOException {
        InputStream inputStream = client.getInputStream();
        OutputStream outputStream = client.getOutputStream();
        BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));

        String requestLine = readRequestLine(inputStream);
        if (requestLine == null) {
            return;
        }

        if (requestLine.contains("GET")) {
            handleGetRequest(requestLine, new PrintWriter(outputStream), outputStream);
        } else if (requestLine.contains("POST")) {
            handlePostRequest(inputStream, outputStream); // ✅ 注意这里改为 inputStream
        }

        client.close();
        Log.e("TAG", "handleClient: " );
    }

    // 读取第一行 HTTP 请求行（如 POST / HTTP/1.1）
    private String readRequestLine(InputStream inputStream) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int prev = 0, curr;
        while ((curr = inputStream.read()) != -1) {
            if (prev == '\r' && curr == '\n') break;
            buffer.write(curr);
            prev = curr;
        }
        return buffer.toString("UTF-8");
    }

    private void handleGetRequest(String request, PrintWriter writer, OutputStream out)
            throws IOException {
        if (request.contains("download")) {
            handleFileDownload(request, out);
        } else if (request.contains("delete")) {
            handleDeleteRequest(request, writer);
        } else {
            sendFileList(writer);
        }
    }

    private void handleDeleteRequest(String request, PrintWriter writer) throws IOException {
        String fileName = request.split("file=")[1].split(" ")[0];
        fileName = URLDecoder.decode(fileName, "UTF-8");
        File file = new File(storageDir, fileName);

        if (file.exists() && file.delete()) {
            writer.println("HTTP/1.1 302 Found");
            writer.println("Location: /");
            writer.println("Connection: close");
            writer.println();
        } else {
            writer.println("HTTP/1.1 302 Found");
            writer.println("Location: /");
            writer.println("Connection: close");
            writer.println();
        }
        writer.flush();
    }

    private void sendFileList(PrintWriter writer) {
        writer.println("HTTP/1.1 200 OK");
        writer.println("Content-Type: text/html; charset=utf-8");
        writer.println("Connection: close");
        writer.println();

        writer.println("<html><head><title>文件服务器</title><script>function validateFile() { var fileInput = document.querySelector('input[type=\\\"file\\\"]'); if (fileInput.files.length === 0) { alert('请选择一个文件上传'); return false; } return true; }</script></head><body>");
        writer.println("<h2>文件列表</h2>");
        writer.println("<form method='POST' enctype='multipart/form-data' onsubmit='return validateFile()'>");
        writer.println("<input type='file' name='file'/>");
        writer.println("<input type='submit' value='上传'/>");
        writer.println("</form>");
        writer.println("<button style='margin: 10px 0;' onclick='location.reload()'>刷新</button>");

        File[] files = storageDir.listFiles();
        if (files != null) {
            for (File file : files) {
                writer.println("<p>");
                writer.println(file.getName() + " (" + String.format("%.2f", file.length() / 1024.0) + " KB) <button onclick=\"window.location.href='/download?file=" + URLEncoder.encode(file.getName()) + "'\" style='margin-left: 10px; margin-right: 5px;'>下载</button>");
                writer.println("<button onclick='if(confirm(\"确定要删除此文件吗？\")) window.location.href=\"/delete?file=" + URLEncoder.encode(file.getName()) + "\"' style='margin-left: 10px; margin-right: 5px;'>删除</button></p>");
            }
        }
        writer.println("</body></html>");
        writer.flush();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

//    private void handleFileDownload(String request, OutputStream out) throws IOException {
//        String fileName = request.split("file=")[1].split(" ")[0];
//        fileName = URLDecoder.decode(fileName, "UTF-8");
//        File file = new File(storageDir, fileName);
//
//        if (file.exists()) {
//            PrintWriter writer = new PrintWriter(out);
//            writer.println("HTTP/1.1 200 OK");
//            writer.println("Content-Type: application/octet-stream");
//            writer.println("Content-Disposition: attachment; filename=\"" + fileName + "\"");
//            writer.println("Content-Length: " + file.length());
//            writer.println();
//            writer.flush();
//
//            FileInputStream fis = new FileInputStream(file);
//            byte[] buffer = new byte[4096];
//            int bytesRead;
//            while ((bytesRead = fis.read(buffer)) != -1) {
//                out.write(buffer, 0, bytesRead);
//            }
//            fis.close();
//        } else {
//            send404(out);
//        }
//    }

    private void handleFileDownload(String requestLine, OutputStream out) throws IOException {
        try {
            String fileName = requestLine.split("file=")[1].split(" ")[0];
            fileName = URLDecoder.decode(fileName, "UTF-8");
            File file = new File(storageDir, fileName);

            if (!file.exists()) {
                send404(out);
                return;
            }

            // 1. 写响应头（必须是字节流）
            String header =
                    "HTTP/1.1 200 OK\r\n" +
                            "Content-Type: application/octet-stream\r\n" +
                            "Content-Disposition: attachment; filename=\"" + fileName + "\"\r\n" +
                            "Accept-Ranges: bytes" + "\r\n" +
                            "Content-Length: " + file.length() + "\r\n" +
                            "Connection: close\r\n\r\n";
//                            "Connection: keep-alive\r\n\r\n";
            out.write(header.getBytes("UTF-8"));
            Log.e("TAG", "handleFileDownload: " + file.length());
            out.flush();

            // 2. 写文件内容
            try (FileInputStream fis = new FileInputStream(file)) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = fis.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }
            }
            out.flush();
            Thread.sleep(100);
        } catch (Exception e) {
            send500(out, e.getMessage());
        }
    }

//    private void handlePostRequest(BufferedReader in, OutputStream out) throws IOException {
////        String boundary = null;
////        String line;
////        while ((line = in.readLine()) != null && !line.isEmpty()) {
////            if (line.contains("boundary=")) {
////                boundary = "--" + line.split("boundary=")[1];
////            }
////        }
////
////        if (boundary == null) {
////            send400(out);
////            return;
////        }
////
////        String fileName = null;
////        while ((line = in.readLine()) != null && !line.equals(boundary + "--")) {
////            if (line.contains("filename=\"")) {
////                fileName = line.split("filename=\"")[1].split("\"")[0];
////            }
////
////            if (line.isEmpty()) {
////                if (fileName != null) {
////                    File file = new File(storageDir, fileName);
////                    FileOutputStream fos = new FileOutputStream(file);
////
////                    while ((line = in.readLine()) != null && !line.startsWith(boundary)) {
////                        fos.write(line.getBytes());
////                        fos.write("\r\n".getBytes());
////                    }
////
////                    fos.close();
////                    sendSuccessResponse(out);
////                    return;
////                }
////            }
////        }
////        send400(out);
//
//        String boundary = null;
//        String line;
//
//        // 1. 解析请求头获取boundary
//        while ((line = in.readLine()) != null && !line.isEmpty()) {
//            if (line.contains("boundary=")) {
//                boundary = "--" + line.split("boundary=")[1];
//                break;
//            }
//        }
//
//        if (boundary == null) {
//            send400(out);
//            return;
//        }
//
//        // 2. 循环处理每个表单字段
//        while ((line = in.readLine()) != null) {
////            if (line.equals("--" + boundary + "--")) {
////                Log.e("TAG", "handlePostRequest: ");
////                sendSuccessResponse(out); // 所有文件处理完成后返回成功响应
////                return;
////                break; // 结束标记
////            }
////            Log.e("TAG", line);
//
//            if (line.contains("filename=\"")) {
//                // 处理文件字段
//                String fileName = line.split("filename=\"")[1].split("\"")[0];
//                String contentType = "";
//
//                // 读取Content-Type（可选）
//                while (!(line = in.readLine()).isEmpty()) {
//                    if (line.startsWith("Content-Type:")) {
//                        contentType = line.split(": ")[1];
////                        Log.e("TAG", line);
//                    }
//                }
//
//                // 读取文件内容
//                File file = new File(storageDir, fileName);
//                FileOutputStream fos = new FileOutputStream(file);
//
//                while ((line = in.readLine()) != null && !line.startsWith(boundary)) {
//                    if (!line.isEmpty()) { // 跳过空行（分隔符）
//                        byte[] buffer = (line + "\r\n").getBytes(); // 保留换行符
//                        fos.write(buffer);
//                        Log.e("TAG", line);
//                    }
//                }
//                        fos.close();
////                Log.e("TAG", line);
////                Log.e("end", boundary);
//                if (line.equals(boundary + "--")) {
//                    sendSuccessResponse(out); // 所有文件处理完成后返回成功响应
//                    return;
//                }
//            }
//        }
////        sendSuccessResponse(out); // 所有文件处理完成后返回成功响应
////        send400(out);
//

    /// /        String boundary = null;
    /// /        String line;
    /// /
    /// /        // 1. 解析请求头获取boundary
    /// /        while ((line = in.readLine()) != null && !line.isEmpty()) {
    /// /            if (line.contains("boundary=")) {
    /// /                boundary = "--" + line.split("boundary=")[1];
    /// /                break;
    /// /            }
    /// /        }
    /// /
    /// /        if (boundary == null) {
    /// /            send400(out);
    /// /            return;
    /// /        }
    /// /
    /// /        // 2. 循环处理每个表单字段
    /// /        while ((line = in.readLine()) != null && !line.equals(boundary + "--")) {
    /// /            if (line.contains("filename=\"")) {
    /// /                // 处理文件字段
    /// /                String fileName = line.split("filename=\"")[1].split("\"")[0];
    /// /                String contentType = "";
    /// /
    /// /                // 读取Content-Type（可选）
    /// /                while (!(line = in.readLine()).isEmpty()) {
    /// /                    if (line.startsWith("Content-Type:")) {
    /// /                        contentType = line.split(": ")[1];
    /// /                    }
    /// /                }
    /// /
    /// /                // 读取文件内容
    /// /                File file = new File(storageDir, fileName);
    /// /                FileOutputStream fos = new FileOutputStream(file);
    /// /
    /// /                while ((line = in.readLine()) != null && !line.startsWith(boundary)) {
    /// /                    if (!line.isEmpty()) { // 跳过空行（分隔符）
    /// /                        byte[] buffer = (line + "\r\n").getBytes(); // 保留换行符
    /// /                        fos.write(buffer);
    /// /                    }
    /// /                }
    /// /                fos.close();
    /// /            } else {
    /// /                // 跳过非文件字段（如普通表单字段）
    /// /                while ((line = in.readLine()) != null && !line.startsWith(boundary)) {
    /// /                    // 忽略非文件内容
    /// /                }
    /// /            }
    /// /        }
    /// /        sendSuccessResponse(out); // 所有文件处理完成后返回成功响应
//
//    }
    private void handlePostRequest(InputStream inputStream, OutputStream out) throws IOException {
        // 1. 读取 headers（直到 \r\n\r\n）
        ByteArrayOutputStream headerBuffer = new ByteArrayOutputStream();
        int prev = 0, curr;
        while ((curr = inputStream.read()) != -1) {
            headerBuffer.write(curr);
            if (prev == '\r' && curr == '\n') {
                byte[] data = headerBuffer.toByteArray();
                int len = data.length;
                if (len >= 4 && data[len - 4] == '\r' && data[len - 3] == '\n' &&
                        data[len - 2] == '\r' && data[len - 1] == '\n') {
                    break; // 遇到 \r\n\r\n
                }
            }
            prev = curr;
        }

        String headers = headerBuffer.toString("ISO-8859-1");
        String boundary = null;
        for (String line : headers.split("\r\n")) {
            if (line.contains("boundary=")) {
                boundary = "--" + line.split("boundary=")[1].trim();
                break;
            }
        }
        if (boundary == null) {
            send400(out);
            return;
        }

        // 2. 读取请求体（剩余部分）
        ByteArrayOutputStream bodyBuffer = new ByteArrayOutputStream();
        byte[] buf = new byte[4096];
        int len;
        String bodyStr = "";
        while ((len = inputStream.read(buf)) != -1) {
            bodyBuffer.write(buf, 0, len);
            bodyStr = bodyBuffer.toString("ISO-8859-1");
            if (bodyStr.contains(boundary + "--")) {
                break;
            }
        }

        byte[] bodyBytes = bodyBuffer.toByteArray();

        // 3. 解析 multipart，每个 boundary 分段就是一个文件字段
        String[] parts = bodyStr.split(boundary);
        int i = 0;
        for (String part : parts) {
            i++;
            if (part.contains("filename=\"")) {
                String[] lines = part.split("\r\n");
                String filename = null;
                for (String line : lines) {
                    if (line.contains("filename=\"")) {
                        filename = line.split("filename=\"")[1].split("\"")[0];
                        break;
                    }
                }
                if (filename == null) continue;

                int start = part.indexOf("\r\n\r\n") + 4;
                int end = part.lastIndexOf("\r\n");
                if (start <= 0 || end <= start) continue;

                byte[] fileData = part.substring(start, end).getBytes("ISO-8859-1");

                File file = new File(storageDir, filename);
                try (FileOutputStream fos = new FileOutputStream(file)) {
                    fos.write(fileData);
//                    if (i == parts.length) {
//                        sendSuccessResponse(out); // 所有文件处理完成后返回成功响应
//                    }
                }
            }
        }

        sendSuccessResponse(out);
    }

    private int indexOf(byte[] source, byte[] target, int from) {
        outer:
        for (int i = from; i <= source.length - target.length; i++) {
            for (int j = 0; j < target.length; j++) {
                if (source[i + j] != target[j]) continue outer;
            }
            return i;
        }
        return -1;
    }

    private void sendSuccessResponse(OutputStream out) throws IOException {
        PrintWriter writer = new PrintWriter(out, true);
        writer.println("HTTP/1.1 200 OK");
        writer.println("Content-Type: text/html; charset=utf-8");
        writer.println();
        writer.println("<html><body>");
        writer.println("<h2>文件上传成功!</h2>");
        writer.println("<a href='/'>返回文件列表</a>");
        writer.println("</body></html>");
        writer.flush();
    }

    private void send404(OutputStream out) throws IOException {
        PrintWriter writer = new PrintWriter(out);
        writer.println("HTTP/1.1 404 Not Found");
        writer.println("Content-Type: text/html; charset=utf-8");
        writer.println();
        writer.println("<html><body><h2>404 文件未找到</h2></body></html>");
        writer.flush();
    }

    private void send400(OutputStream out) throws IOException {
        PrintWriter writer = new PrintWriter(out);
        writer.println("HTTP/1.1 400 Bad Request");
        writer.println("Content-Type: text/html; charset=utf-8");
        writer.println();
        writer.println("<html><body><h2>400 请求错误</h2></body></html>");
        writer.flush();
    }

    private void send500(OutputStream out, String msg) throws IOException {
        String body = "<html><body><h2>服务器出错</h2><pre>" + msg + "</pre></body></html>";
        String header =
                "HTTP/1.1 500 Internal Server Error\r\n" +
                        "Content-Type: text/html; charset=utf-8\r\n" +
                        "Content-Length: " + body.getBytes("UTF-8").length + "\r\n" +
                        "Connection: close\r\n\r\n";

        out.write(header.getBytes("UTF-8"));
        out.write(body.getBytes("UTF-8"));
        out.flush();
    }

    public void stop() {
        isRunning = false;
        try {
            if (serverSocket != null) serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
